package com.example.callbackservice.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.example.callbackservice.entity.CallbackBody;
import com.example.callbackservice.entity.CallbackComponent;
import com.example.common.entity.CallbackConfig;
import com.example.common.utils.CryptUtil;
import com.example.common.utils.SHA1;
import com.example.common.utils.WillingAESUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

/**
 * @author Destinycc
 */
@Slf4j
public class CallbackUtils {

    /**
     * 构建callback的请求request，包含
     * 请求头header
     * 请求体body
     * @param appId
     * @param encrypted
     * @return
     */
    public static HttpEntity buildBody(String appId, String encrypted) {
        CallbackBody body = new CallbackBody(appId, encrypted);
        HttpHeaders headers = new HttpHeaders();
        //设置mediaType，防止出现中文乱码
        MediaType type = MediaType.parseMediaType("application/json;charset=UTF-8");
        headers.setContentType(type);
        return new HttpEntity(JSON.toJSON(body), headers);
    }

    /**
     * 构建callback所需的所有参数，包含
     * encrypted 加密后的msg
     * msgSignature 签名
     * timeStamp 时间戳
     * nonce 16位随机串
     * @param cfg
     * @param msg
     * @return
     * @throws Exception
     */
    public static CallbackComponent buildCallbackComponent(CallbackConfig cfg, Object msg) throws Exception {
        String token = WillingAESUtils.decrypt(cfg.getToken());
        String encodingAesKey = WillingAESUtils.decrypt(cfg.getEncodingAesKey());
        CryptUtil cryptUtil = new CryptUtil(token, encodingAesKey, cfg.getAppId());
        SerializeConfig config = new SerializeConfig();
        config.setPropertyNamingStrategy(PropertyNamingStrategy.SnakeCase);
        String jsonMag = JSON.toJSONString(msg, config);
        String encrypted = cryptUtil.encrypt(jsonMag);
        log.info("change msg json str :{}\n, encrypted: {}", jsonMag, encrypted);
        String nonce = CryptUtil.genRandomStr(16);
        String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
        String msgSignature = SHA1.gen(token, timeStamp, nonce, encrypted);
        return new CallbackComponent(encrypted, msgSignature, timeStamp, nonce);
    }
}
